#!/bin/sh
set -uxe
echo "`date`"
echo "Start make TQE"

export HOME="/root"
TQEDIR="/usr1/jenkins/plugins/CodeDEX_V3/tool/tools/coverity"
FORTIFYDIR="/usr1/jenkins/plugins/CodeDEX_V3/tool/tools/fortify"
CODEMARSDIR="/usr1/jenkins/plugins/CodeDEX_V3/tool/tools/codemars_Newest"
BINSCOPEDIR="/usr1/jenkins/plugins/CodeDEX_V3/tool/tools/binscope"
CI_PROJECT=`pwd | awk -F'/' '{print $(NF-2)}'`
CPATH="/usr1/CISrc/${CI_PROJECT}"
TMPCPATH=`pwd`
OBSSERVER_IP="100.109.85.100"
set +u
if [ "x${obs_server_from_jenkins}" != "x" ]; then
    OBSSERVER_IP="${obs_server_from_jenkins}"
fi
set -u

function init_osc()
{
    set +e
    rm -f /root/.config/osc/trusted-certs/euleros-obs_443.pem
    if which osc &> /dev/null; then
        log_info "osc has been here"
    else
        url1="http://10.175.100.158/iso/SLE:/12:/SP2/SLE-12-SP2-SDK-DVD-x86_64-GM-DVD1"
        url2="http://10.175.100.158/iso/SLE:/12:/SP2/SLE-12-SP2-Server-DVD-x86_64-GM-DVD1"

        repo=`zypper lr | awk '{if(NR>2)print $1}'`
        if [ -n "$repo" ];then
            zypper rr $repo
        fi

        zypper ar $url1 sdk
        zypper ar $url2 dvd
        zypper ref -f
        zypper --non-interactive install osc
    fi

    cat << EOF > /root/.oscrc
[general]
apiurl = https://euleros-obs
no_verify = 1

[https://euleros-obs]
user=root
pass=EulerOS_123
EOF

    expect -c "
        set timeout 300
        spawn osc ls SUSE:SLE-11:SP3
            expect {
                \"Enter choice*:\" {send \"2\r\"; exp_continue}
            }
    "
    osc ls SUSE:SLE-11:SP3
    if [ $? -ne 0 ]; then
        log_error "failed: when osc ls SUSE:SLE-11:SP3"
    fi
    set -e
}

function check_env()
{
    if ! which osc &> /dev/null; then
        init_osc
    fi
cat << END1 > /root/.oscrc
[general]
apiurl = https://euleros-obs
no_verify = 1

[https://euleros-obs]
user = root
pass = EulerOS_123
END1

    if [ "$OBSSERVER_IP"   ==   "100.109.85.100" ];then
        OBSUI_IP="100.109.85.108"
    else
        OBSUI_IP="$OBSSERVER_IP"
    fi

    sed -i '/euleros-obs/d' /etc/hosts
    echo "$OBSSERVER_IP euleros-obs-repo.huawei.com euleros-obs-repo" >> /etc/hosts
    echo "$OBSUI_IP euleros-obs.huawei.com euleros-obs" >> /etc/hosts
    rm -f /root/.config/osc/trusted-certs/euleros-obs_443.pem
expect -c "
    set timeout -1
    spawn osc ls SUSE:SLE-11:SP3
    expect {
        \"Enter choice*\" {send \"2\r\" ; exp_continue }
        eof { catch wait result; exit [lindex \$result 3] }
     }
     expect {
         eof { catch wait result; exit [lindex \$result 3] }
     }
"
if [ $? -ne 0 ]; then
    echo "FAILED: WHEN osc ls SUSE:SLE-11:SP3"
    exit 1
fi
}

#从obs上下载最新的模块代码
function checkout_package()
{
    pro="$1"
    pack="$2"
    rm -rf "$pro"
    set +e
    osc co "$pro" "$pack"
    if [ $? -ne 0 ]; then
        sleep 60
        osc co "$pro" "$pack"
        if [ $? -ne 0 ]; then
            sleep 90
            osc co "$pro" "$pack"
            if [ $? -ne 0 ]; then
                echo "ERROR: osc co $pro $pack failed"
                exit 1
            fi
        fi
    fi
    set -e
}

#修改带_service的文件名称
function rename_obsfile()
{
    dir=$1
    pushd $dir
    set +e
    if [ -f '_service' ]; then
        osc up -S
        if [ $? -ne 0 ]; then
            sleep 60
            osc up -S
            if [ $? -ne 0 ]; then
                sleep 90
                osc up -S
                if [ $? -ne 0 ]; then
                    echo "Failed: osc up -S"
                    exit 1
                fi
            fi
        fi
        rm -rf '_service'
    fi
    set -e

    for file in `ls`
    do
        [[ -d $file ]] && continue
        newfile=${file##_service*:}
        mv $file $newfile
    done
    popd
}

#创建编译环境
function create_buildroot()
{
    #clean obs cache
    rm -rf /var/tmp/osbuild-packagecache
    echo "clean obs cache:  rm -rf /var/tmp/osbuild-packagecache"
    prj=$1
    pkg=$2
    dir=$3
    mkdir -p $dir
    pushd $prj/$pkg
    sed  -i "1i\BuildRequires: -custom_build_tool-uploadbuild" *.spec
    sed  -i "/^rm -rf %{buildroot}[ ]*$/ d"   *.spec
    sed  -i "/^rm -rf %{_builddir}[ ]*$/ d" *.spec
    if [ $2 = "lxcfs" ]; then
       sed -i 's/rm bindings.h/ /g'  lxcfs.spec
    fi
expect -c "
     set timeout -1
     spawn osc build standard_x86_64 --root $dir
     expect {
         \"*trust packages just this time*\" {send \"1\r\";exp_continue}
         eof { catch wait result; exit [lindex \$result 3] }
     }
     expect {
         eof { catch wait result; exit [lindex \$result 3] }
     }
"
    if [ $? -ne 0 ]; then
        echo "Failed: osc build --root $dir"
        clean_build_root $dir
        exit 1
    fi
    popd
}

#配置TQE的执行环境
function tqe_conf()
{
    tqedir=$1
    dir=$2
    profile="$dir/etc/profile"
    cp -r $tqedir $dir
    if [ ! -f $profile ]; then
        echo "Failed: there is no $profile"
        exit 1
    fi

    set +e
    num=`grep -c "COV_BIN" $profile`
    set -e
    if [ $num -ne 0 ]; then
        echo "the TQE had installed"
    else
        echo "export COV_BIN=/coverity/bin" >> $profile
        echo "export PATH=\$COV_BIN:\$PATH" >> $profile
    fi
}

#config binscope
function binscope_conf()
{
    binscope_dir=$1
    dir=$2
    profile="$dir/etc/profile"
    cp -a $binscope_dir $dir
    cp -a $binscope_dir/../compiler-extract $dir
    chmod -R 777 $dir/binscope
    chmod -R 777 $dir/compiler-extract
    if [ ! -f $profile ]; then
        echo "Failed: there is no $profile"
        exit 1
    fi

    set +e
    num=`grep -c "BINSCOPE_BIN" $profile`
    set -e
    if [ $num -ne 0 ]; then
        echo "the BINSCOPE had been installed"
    else
        echo "export BINSCOPE_BIN=/binscope" >> $profile
        echo "export PATH=\$BINSCOPE_BIN:\$PATH" >> $profile
    fi
}

#配置fortify的执行环境
function fortify_conf()
{
    fortify_dir="$1"
    dir=$2
    profile="$dir/etc/profile"
    cp -r $fortify_dir $dir/
    if [ $? -ne 0 ]; then
        echo "Failed: when cp $fortify_dir to $dir/"
        exit 1
    fi
    set +e
    num=`grep -c "FORTIFY_BIN" $profile`
    set -e
    if [ $num -ne 0 ]; then
        echo "the FORTIFY had installed"
    else
        echo "export FORTIFY_BIN=/fortify/bin" >> $profile
        echo "export PATH=\$FORTIFY_BIN:\$PATH" >> $profile
    fi
}

function CodeMars_conf()
{
    CodeMars_dir="$1"
    dir="$2"
    profile="$dir/etc/profile"
    cp -r "$CodeMars_dir"/../codemars_Newest $dir/
    cp -r "$CodeMars_dir"/../../7za $dir/
    cp -r "$CodeMars_dir"/../jdk1.8.0_162 $dir/
    #配置codmars java的执行环境
    set +e
    jnum="$(grep -c "JAVA_HOME" $profile)"
    set -e
    if [ "$jnum" -ne 0 ] ; then
        echo "the TQE had installed"
    else
        echo "export JAVA_HOME=/jdk1.8.0_162/bin" >> $profile
        echo "export PATH=\$JAVA_HOME:\$PATH" >> $profile
    fi
    mount --bind /proc $dir/proc
    cp -r /lib/* $dir/lib/

}

function clean_build_root()
{
    dir=$1
    set +e
    umount $dir/proc
    umount $dir/dev/pts
    set -e
    rm -rf $dir
}

function clean_build_root_exit()
{
    status=$?
    dir=$1
    if [ $status -ne 0 ]; then
        set +e
        umount $dir/proc
        umount $dir/dev/pts
        set -e
        rm -rf $dir
    fi
}

######################
# 用法：
# 1.Usage:  env_config.sh --project $PROJECT --package $PACKAGE -工具 或 --except 工具 或 --all  --type 语言 -src
#   -工具：-cov -fortify -CodeMars -binscope 可以多选; --except cov/fortify/CodeMars/binscope 选择其中一个工具,除了这个工具，其余工具都使用; --all 使用所有工具
#   --type: --type sh cov扫描使用shell命令
#   -src 扫描不带_service的文件
######################
function fun_main()
{
    TYPE=''
    src=''
    except=''
    cov=''
    fortify=''
    CodeMars=''
    binscope=''
    cov_dif=''
    while test $# -gt 0; do
        case $1 in
          *-project)
            PROJECT="$2"
            shift
          ;;
          *-package)
            PACKAGE="$2"
            shift
          ;;
          *-type)
            TYPE="$2"
            shift
          ;;
          *src)
           src="src"
          ;;
          *cov)
           cov="cov"
          ;;
          *fortify)
           fortify="fortify"
          ;;
          *CodeMars)
           CodeMars="CodeMars"
          ;;
          *binscope)
           binscope="binscope"
          ;;
          *-all)
           cov="cov"
           fortify="fortify"
           CodeMars="CodeMars"
           binscope="binscope"
          ;;
          ##除了输入的工具之外，其余工具都使用
          *-except)
           except="$2"
           shift
          ;;
          *)
            echo "Unknown parameter: $1"
            echo "1.Usage:  env_config.sh --project $PROJECT --package $PACKAGE -工具 或 --except 工具 或 --all  --type 语言 -src"
            echo " -工具：-cov -fortify -CodeMars -binscope 可以多选; --except cov/fortify/CodeMars/binscope 选择其中一个工具,除了这个工具，其余工具都使用; --all 使用所有工具"
            echo " --type: --type sh cov扫描使用shell命令"
            echo " -src 扫描不带_service的文件"

            exit 1
          ;;
        esac
          shift
    done

    check_env
    mkdir -pv $CPATH
    echo "$CPATH" > project_name
    tqe_result="/usr1/tqe_result/$CI_PROJECT/$PACKAGE"
    echo $tqe_result > $CPATH/last_tqe_result
    rm -rf $tqe_result
    mkdir  -pv $tqe_result

    BUILDROOT="$CPATH/$PROJECT/$PACKAGE/build-root"
    echo $BUILDROOT > $CPATH/last_building
    trap "clean_build_root_exit $BUILDROOT" EXIT
    checkout_package "$PROJECT" "$PACKAGE"
    if [ -z "$src" ];then
        rename_obsfile "$PROJECT/$PACKAGE"
    fi
    clean_build_root $BUILDROOT
    create_buildroot $PROJECT $PACKAGE $BUILDROOT

    if [ ! -d $TQEDIR ]; then
        echo "Failed: There is no TQE dir"
        exit 1
    fi
    #执行cov make的动作
    #ln是解决uname -r获取内核版本号不对的问题，如果不是内核模块下面的可能会执行失败，但是不影响
    if [ ! -f $BUILDROOT/.build.log ]; then
        echo "Failed:osc build error"
        exit 1
    fi
    rpmbuild_dir="$(cat $BUILDROOT/.build.log  | grep '.src.rpm' | awk '{print $NF}' | sed 's/[ :]//g' | awk -F'SRPMS' '{print $1}')"
    cov_dir="$rpmbuild_dir"/BUILD/
    echo "$TYPE" > "$CPATH/last_build_type"
    if [ "x$TYPE"   ==   "x" -o "$TYPE"   ==   "cplus" -o  "$TYPE" == "sh" ]; then
         create_make
         create_environment "$PACKAGE"
         create_tools
    else
        echo "--type $TYPE cant not recongsize"
        exit 1
    fi
    if [ -f "build.sh" ];then
        mv build.sh "$BUILDROOT"/
    fi
    mv do_make.sh $BUILDROOT/
    exit 0
}


function create_make()
{

cat <<END1 >> do_make.sh
#!/bin/bash
kernel_ver=`uname -r`
rm -rf /lib/modules/\${kernel_ver}
ln -s /lib/modules/*-default /lib/modules/\${kernel_ver}
source /etc/profile
cd "$cov_dir"/\$1
make clean
find "$cov_dir"  -name "*.o" | xargs rm -f
mkdir cov
END1

}



function create_tools()
{
rm -rf $CPATH/tools.txt
if [ -z "$except"  ];then
	if [ "$cov"  ==  "cov" ];then
                echo "cov" >> $CPATH/tools.txt
                tqe_conf $TQEDIR $BUILDROOT
		if [ "$TYPE"   ==   "sh" ];then
		     create_coverity_sh
		else
		     create_coverity
		fi
	fi
	if [ "$fortify"  ==  "fortify" ] ;then
                echo "fortify" >> $CPATH/tools.txt
                fortify_conf $FORTIFYDIR $BUILDROOT
		create_fortify
	fi
	if [ "$CodeMars"  ==  "CodeMars"  ];then
                echo "CodeMars" >> $CPATH/tools.txt
                CodeMars_conf $CODEMARSDIR $BUILDROOT
		create_CodeMars
	fi
	if [  "$binscope"  ==  "binscope"  ];then
                binscope_conf $BINSCOPEDIR $BUILDROOT
                echo "binscope" >> $CPATH/tools.txt
		create_binscope
	fi
else
    if [ "$except" != "cov" ];then
            echo "cov" >> $CPATH/tools.txt
            tqe_conf $TQEDIR $BUILDROOT
            if [ "$TYPE"   ==   "sh" ];then
                 create_coverity_sh
            else
                 create_coverity
            fi
    fi
    if [ "$except" != "fortify" ] ;then
            echo "fortify" >> $CPATH/tools.txt
            fortify_conf $FORTIFYDIR $BUILDROOT
            create_fortify
    fi
    if [ "$except" != "CodeMars"  ];then
            echo "CodeMars" >> $CPATH/tools.txt
            CodeMars_conf $CODEMARSDIR $BUILDROOT
            create_CodeMars
    fi
    if [ "$except" !=  "binscope"  ];then
            echo "binscope" >> $CPATH/tools.txt
            binscope_conf $BINSCOPEDIR $BUILDROOT
            create_binscope
    fi
fi



}


function create_coverity_sh()
{
cat <<END1 >> do_make.sh
rm -rf build.sh
mv /build.sh ./
cov-build --dir cov sh build.sh
tqe_result=\$?
echo \$tqe_result > /tqe_make_result
END1
}

function create_coverity()
{
cat <<END1 >> do_make.sh
cov-build --dir cov make \$2
tqe_result=\$?
echo \$tqe_result > /tqe_make_result
END1
}


function create_fortify()
{
cat <<END1 >> do_make.sh
Language="\$3"
if [ "\$Language" == "py" ]; then
    source /etc/profile
    export FORTIFY_HOME=/fortify
    export PATH=\$FORTIFY_HOME/bin:\$PATH
    export BUILD_ID=package
    export ProjectRoot="$cov_dir"/\$1
    export PythonPath=/usr/bin/python
    sourceanalyzer -b \$BUILD_ID -clean
    sourceanalyzer -b \$BUILD_ID \$ProjectRoot/**/*.py -python-path \$PythonPath # -django-template-dirs <path/to/template/dirs>
    cd /root/.fortify/
    /fortify/bin/sourceanalyzer -b \$BUILD_ID -export-build-session \$BUILD_ID.mbs
    fortify_result=\$?
    echo \$fortify_result > /fortify_make_result
elif [ -z "\$4" ];then
    ##默认以cmake方式编译
    make clean
    sourceanalyzer -b packag -clean
    /compiler-extract/bin/compiler-extract  -lang c -fh /fortify -ch /coverity -covdir "$cov_dir"/\$1/cov -fordir /root/.fortify -b "packag"
    fortify_result=\$?
    echo \$fortify_result > /fortify_make_result
    cd /root/.fortify
    sourceanalyzer -b "packag" -Dcom.fortify.sca.ProjectRoot="/root/.fortify" -export-build-session packag.mbs
elif [ "\$4" == "make" ];then
    make clean
    sourceanalyzer -b packag -clean
    sourceanalyzer -b packag touchless make \$2
    fortify_result=\$?
    echo \$fortify_result > /fortify_make_result
    cd /root/.fortify
    sourceanalyzer -b "packag" -Dcom.fortify.sca.ProjectRoot="/root/.fortify" -export-build-session packag.mbs
fi
END1
}

function create_CodeMars()
{

cat <<END1 >> do_make.sh
mv $cov_dir/\$1/cov /
cd /codemars_Newest
Language="\$3"
if [ -n "\$Language" ]; then
    sh CodeMars.sh -\$Language -tool -source "$cov_dir/\$1" -output "/codemars_Newest/CodeMars.json"
else
    sh CodeMars.sh -c -tool SecFinder-C  -source "$cov_dir/\$1" -output "/codemars_Newest/CodeMars.json"
fi
mv /cov $cov_dir/\$1/
cd -
rm -rf sca17.2
END1

}

function create_binscope()
{

cat <<END1 >> do_make.sh
mkdir -p /binscope
cd /binscope
./binscope  -m -d  "$cov_dir"\$1 -r  \$1

END1
}

source ./create_environment.sh

fun_main $@
